
package org.openeai.lite.common.control;

import org.apache.camel.spring.Main;
import org.apache.log4j.Logger;
import org.openeai.lite.common.exception.OpenEAIException;
import org.openeai.lite.common.util.Constants;
import org.openeai.lite.common.util.FileUtils;
import org.springframework.context.support.AbstractApplicationContext;


public class RouterController
{

    private static Logger log = Logger.getLogger(RouterController.class);

    private AbstractApplicationContext context = null;

    // run controller as singleton
    private static volatile RouterController instance;

    private static final Object instanceLock = new Object();

    private RouterController()
    {
    };

    /**
     * Get the {@link RouterController} singleton instance in a thread safe way
     * (Java 1.5+ !!!)
     * 
     * @return The {@link RouterController} singleton instance.
     */
    public static RouterController getInstance()
    {
        if (instance == null)
        {
            synchronized (instanceLock)
            {
                if (instance == null)
                {
                    log.info("Creating new Message Router Controller instance");
                    instance = new RouterController();
                }
            }
        }
        return instance;
    }

    public AbstractApplicationContext getContext() throws OpenEAIException
    {
        return this.context;

    }

    public synchronized void start(String startupType, String configuration) throws OpenEAIException
    {
        try
        {
            Main main = new Main();
            if (!isStarted())
            {
                if (startupType == null || startupType.equals(Constants.STARTUP_NORMAL))
                {
                    log.info("Camel configuration set to " + Constants.ROUTER_CONFIG_DEFAULT);
                    main.setApplicationContextUri(Constants.ROUTER_CONFIG_DEFAULT);
                }
                else if (startupType.equals(Constants.STARTUP_CUSTOM) && configuration != null)
                {
                    log.info("Camel config file set to " + configuration);
                    String uri = new FileUtils().fileNameToURI(configuration).toString();
                    log.info("Starting Message Router with configuration file " + uri);
                    main.setApplicationContextUri(uri);
                }
                else
                {
                    throw new OpenEAIException("Error starting Message Router with startup type "
                                    + startupType + " and optional configuration " + configuration);
                }


                log.info("Starting message router.");
                main.enableHangupSupport();
                main.start();

                log.info("Retrieving Camel context.");
                this.context = main.getApplicationContext();
            }
            else
            {
                log.info("Message router already started.");
            }            
        }
        catch (Exception e)
        {
            log.error("Error starting Message Router: " + e.getMessage());
            throw new OpenEAIException("Error starting Message Router: ", e);
        }
    }


    public synchronized void stop() throws OpenEAIException
    {
        try
        {
            if (isStarted())
            {
                log.info("Stopping message router.");
                this.context.stop();
            }
            else
            {
                log.info("Message router already inactive.");
            }
        }
        catch (Exception e)
        {
            log.error("Error stopping message router");
            throw new OpenEAIException(e);
        }
    }

    public boolean isStarted() throws OpenEAIException
    {
        boolean isRunning = false;
        try
        {
            isRunning = this.context.isRunning();
        }
        catch (Exception e)
        {
            //log.info("Cannot determining status. Assuming message router is not active.");
        }
        return isRunning;
    }

    public Long getStartupDate()
    {
        return this.context.getStartupDate();
    }

}
